package com.fire.control.system.config.mqtt.subscribe.warning;

import java.util.Date;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHandler;
import org.springframework.messaging.MessagingException;
import org.springframework.stereotype.Component;

import com.fire.control.system.config.redis.RedisService;
import com.fire.control.system.dto.LoraDecoder;
import com.fire.control.system.dto.MqttDev;
import com.fire.control.system.entity.WarningProtocol;
import com.fire.control.system.module.warning.service.WarningProtocolService;
import com.fire.control.system.module.warning.service.WarningService;
import com.fire.control.system.statics.Key;
import com.fire.control.system.support.util.LoraDecoderUtil;
import com.google.gson.Gson;


/**
* @ClassName: MqttMessageHandler_SubWarning
* @Description: TODO(接收消息-报警处理)
* @author wanbo
* @date 2017年6月15日 下午3:09:08
*/
@Component
public class MqttMessageHandler_SubWarning implements MessageHandler{
	
	private static final Logger logger = LoggerFactory.getLogger(MqttMessageHandler_SubWarning.class);
	
	@Autowired private WarningService warningService;
	@Autowired private WarningProtocolService warningProtocolService;
	@Autowired private RedisService redisService;
	
	@Override
	public void handleMessage(Message<?> message) throws MessagingException {
		String msg = message.getPayload().toString();//此msg包含网关与节点信息
		if(StringUtils.isNotEmpty(msg) && msg.indexOf("devEUI")>-1){//目前只取节点信息
			MqttDev dev = new Gson().fromJson(msg, MqttDev.class);
			dev.setMsg(msg);
			String fport = dev.getfPort();
			String data = dev.getData();
			String devEUI = dev.getDevEUI();
			
			/**处理报警信息*/
			if(StringUtils.isNotEmpty(data)){//节点信息包含报警状态和节点信息两种
				logger.info(msg);
				WarningProtocol warningProtocol = warningProtocolService.getWarningProtocolByFport(fport);
				//判断报警类型是否匹配系统设置的
				if(warningProtocol!=null){
					//协议数据解析
					LoraDecoder loraDecoder = LoraDecoderUtil.decoder(data, warningProtocol);
					//判断是否报警
					if(loraDecoder.isAlarm()){
						logger.info("--->【注意】报警了devEUI:"+devEUI);
						String warningType = warningProtocol.getWarningType();
						//节点+报警类型作为分布式锁,防止分布式环境重复处理报警信息
						String lockKey = Key.redis_key_lora_lock_ + devEUI + "_" + warningType;
						boolean result = redisService.lock(lockKey);
						if(result){
							try{
								//触发报警,记录报警信息#目前报警时间获取有误,暂用系统当前时间
								warningService.changeWarningProtocol(devEUI, fport, warningType, new Date(), loraDecoder.getWarningDesc(), msg);
							}finally{
								//任何情况下都要释放该锁
								redisService.unlock(lockKey);
							}
						}else{
							logger.info("--->获取锁失败,已有机器处理这条信息devEUI:"+devEUI);
						}
					}else{
						logger.info("----->节点正常devEUI:"+devEUI);
					}
				}else{
					logger.info("----->无此报警解析协议devEUI:"+devEUI);
				}
			}
			
			/** 设备接入 */
			if(StringUtils.isNotEmpty(dev.getDevAddr())){
				//忽略,由巡检员提交申请维护,后台审核完成改变 设备状态和报警信息状态
			}
			
			
			/**接收节点信息保存至redis,作用于设备是否离线 - 此记录信息不需要锁*/
			dev.setReceiveTime(new Date());
			redisService.setObject(Key.redis_key_lora_devEUI_.toString()+dev.getDevEUI(), dev);
			
		}
	}
	
}
